package de.recipeminer.persistence;

/**
 * Enables an instance of class {@code T} to create a {@link Db4oObjectCompanion} that uses
 * that instance as associated object.
 * This interface also defines instance methods for class {@code T} that define the decision
 * about 'db4o equality' of an in-memory-object and objects of the same class saved in the
 * db4o. This seperate notion of equality is required to decide about whether an in-memory object
 * already has a counterpart saved in the db4o database or not.
 * 
 * @author Markus Ackermann
 */
public interface Db4oCompanionProvider<T> {

    /**
     * Creates the {@link Db4oObjectCompanion} for the calling instance of {@code T}.
     * Typically an implementation just returns the return value of {@link Db4oCompanionFactory#companionFor}
     * 
     * @return the object companion for the calling object
     */
    Db4oObjectCompanion<? extends Db4oCompanionProvider<T>> getDb4oCompanion();

    /**
     * Returns an key to decide about equality of objects within der Db4o database.
     * This key can be seen as equivalent to a primary key in a relational database
     * to decide about references to the identical data sets.
     * Storage operations of the {@link Db4oObjectCompanion} will attempt to ensure
     * that only one object of class {@code T} with the returned identifier will
     * exists in the database.
     * This method should be a plain, conditionless getter for the field which name is
     * returned by {@link #db4oIdentifierFieldName()}.
     * 
     * @return a string used as primary identifier to decide about 'record identitiy'
     */
    String db4oIdentifier();

    /**
     * Returns the literal name of the field where the db4o identifier for this object ist saved.
     * The return value of this method has to be consistent with the return value of {@link #db4oIdentifier()}.
     * 
     * 
     * @return name of the field where the db4o identifier for the implementing class is saved
     */
    String db4oIdentifierFieldName();

    /**
     * Ensures that the value of the identifier field (see: {@link #db4oIdentifierFieldName()})
     * is up to date. This method is called before the {@link Db4oObjectCompanion} for the
     * associated objects queries for identical objects in the database or before the
     * associated object is saved.
     * For classes whose identifier field will never change after its initialisation, this
     * method should just be implemented with an empty method body (as there are no
     * update operations necessary).
     * 
     */
    void updateIdentifier();
    
    
    /**
     * This method is called by {@link Db4oObjectCompanion} before every attempt to
     * store the associated object into the database to ensure only objects with a
     * consitent,legal state are saved
     * 
     * @return true, if associated object is in a valid state, else false
     */
    boolean validate();
}
